home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 15 / CU Amiga Magazine's Super CD-ROM 15 (1997)(EMAP Images)(GB)[!][issue 1997-10].iso / CUCD / Graphics / Ghostscript / source / gximage.c < prev    next >
C/C++ Source or Header  |  1997-06-13  |  25KB  |  775 lines

  1. /* Copyright (C) 1989, 1995, 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* gximage.c */
  20. /* Image setup procedures for Ghostscript library */
  21. #include "gx.h"
  22. #include "math_.h"
  23. #include "memory_.h"
  24. #include "gpcheck.h"
  25. #include "gserrors.h"
  26. #include "gsstruct.h"
  27. #include "gxfixed.h"
  28. #include "gxfrac.h"
  29. #include "gxarith.h"
  30. #include "gxmatrix.h"
  31. #include "gsccolor.h"
  32. #include "gspaint.h"
  33. #include "gzstate.h"
  34. #include "gxdevice.h"
  35. #include "gzpath.h"
  36. #include "gzcpath.h"
  37. #include "gxdevmem.h"
  38. #include "gximage.h"
  39. #include "gdevmrop.h"
  40.  
  41. /* Structure descriptor */
  42. private_st_gx_image_enum();
  43.  
  44. /* Strategy procedures */
  45. gx_image_strategies_t image_strategies;
  46.  
  47. /* Define the procedures for initializing gs_image_ts to default values. */
  48. private void
  49. image_t_init(gs_image_t *pim, bool mask)
  50. {    pim->Width = pim->Height = 0;
  51.     gs_make_identity(&pim->ImageMatrix);
  52.     pim->BitsPerComponent = 1;
  53.     /* Doesn't fill in ColorSpace. */
  54.     /* Doesn't fill in Decode. */
  55.     pim->Interpolate = false;
  56.     pim->ImageMask = pim->adjust = mask;
  57.     pim->CombineWithColor = false;
  58. #ifdef DPNEXT
  59.     pim->HasAlpha = false;
  60. #endif
  61. }
  62. void
  63. gs_image_t_init_mask(gs_image_t *pim, bool write_1s)
  64. {    image_t_init(pim, true);
  65.     pim->ColorSpace = NULL;
  66.     if ( write_1s )
  67.       pim->Decode[0] = 1, pim->Decode[1] = 0;
  68.     else
  69.       pim->Decode[0] = 0, pim->Decode[1] = 1;
  70. }
  71. void
  72. gs_image_t_init_gray(gs_image_t *pim)
  73. {    image_t_init(pim, false);
  74.     pim->ColorSpace = gs_color_space_DeviceGray();
  75.     pim->Decode[0] = 0;
  76.     pim->Decode[1] = 1;
  77. }
  78. void
  79. gs_image_t_init_color(gs_image_t *pim)
  80. {    gs_image_t_init_gray(pim);
  81.     pim->ColorSpace = gs_color_space_DeviceRGB();
  82.     pim->Decode[2] = pim->Decode[4] = pim->Decode[6] = 0;
  83.     pim->Decode[3] = pim->Decode[5] = pim->Decode[7] = 1;
  84. #ifdef DPNEXT
  85.     pim->Decode[8] = 0, pim->Decode[9] = 1;
  86. #endif
  87. }
  88.  
  89. /* GC procedures */
  90. #define eptr ((gx_image_enum *)vptr)
  91. private ENUM_PTRS_BEGIN(image_enum_enum_ptrs) {
  92.     int bps;
  93.     gs_ptr_type_t ret;
  94.     /* Enumerate the used members of clues.dev_color. */
  95.     index -= gx_image_enum_num_ptrs;
  96.     bps = eptr->unpack_bps;
  97.     if ( eptr->spp != 1 )
  98.       bps = 8;
  99.     else if ( bps > 8 || eptr->unpack == sample_unpack_copy )
  100.       bps = 1;
  101.     if ( index >= (1 << bps) * st_device_color_max_ptrs ) /* done */
  102.       return 0;
  103.     ret = (*st_device_color.enum_ptrs)
  104.       (&eptr->clues[(index / st_device_color_max_ptrs) *
  105.             (255 / ((1 << bps) - 1))].dev_color,
  106.        sizeof(eptr->clues[0].dev_color),
  107.        index % st_device_color_max_ptrs, pep);
  108.     if ( ret == 0 )        /* don't stop early */
  109.       ENUM_RETURN(0);
  110.     return ret;
  111.     }
  112. #define e1(i,elt) ENUM_PTR(i,gx_image_enum,elt);
  113.     gx_image_enum_do_ptrs(e1)
  114. #undef e1
  115. ENUM_PTRS_END
  116. private RELOC_PTRS_BEGIN(image_enum_reloc_ptrs) {
  117.     int i;
  118. #define r1(i,elt) RELOC_PTR(gx_image_enum,elt);
  119.     gx_image_enum_do_ptrs(r1)
  120. #undef r1
  121.     { int bps = eptr->unpack_bps;
  122.       if ( eptr->spp != 1 )
  123.         bps = 8;
  124.       else if ( bps > 8 || eptr->unpack == sample_unpack_copy )
  125.         bps = 1;
  126.       for ( i = 0; i <= 255; i += 255 / ((1 << bps) - 1) )
  127.         (*st_device_color.reloc_ptrs)
  128.           (&eptr->clues[i].dev_color, sizeof(gx_device_color), gcst);
  129.     }
  130. } RELOC_PTRS_END
  131. #undef eptr
  132.  
  133. /* Forward declarations */
  134. private int color_draws_b_w(P2(gx_device *dev,
  135.                    const gx_drawing_color *pdcolor));
  136. private void image_init_map(P3(byte *map, int map_size, const float *decode));
  137. private void image_init_colors(P9(gx_image_enum *penum, int bps, int spp,
  138.                   bool multi, const float *decode,
  139.                   const gs_imager_state *pis, gx_device *dev,
  140.                   const gs_color_space *pcs, bool *pdcb));
  141.  
  142. /* Procedures for unpacking the input data into bytes or fracs. */
  143. /*extern sample_unpack_proc(sample_unpack_copy);*/    /* declared above */
  144. extern sample_unpack_proc(sample_unpack_1);
  145. extern sample_unpack_proc(sample_unpack_2);
  146. extern sample_unpack_proc(sample_unpack_4);
  147. extern sample_unpack_proc(sample_unpack_8);
  148. sample_unpack_proc((*sample_unpack_12_proc));        /* optional */
  149.  
  150. /* The image_render procedures work on fully expanded, complete rows. */
  151. /* These take a height argument, which is an integer >= 0; */
  152. /* they return a negative code, or the number of */
  153. /* rows actually processed (which may be less than the height). */
  154. /* height = 0 is a special call to indicated that the image has been */
  155. /* fully processed; this is necessary because the last scan lines of */
  156. /* the source data may not produce any output. */
  157.  
  158. /* Start processing an image. */
  159. int
  160. gx_default_begin_image(gx_device *dev,
  161.   const gs_imager_state *pis, const gs_image_t *pim,
  162.   gs_image_format_t format, const gs_int_rect *prect,
  163.   const gx_drawing_color *pdcolor, const gx_clip_path *pcpath,
  164.   gs_memory_t *mem, void **pinfo)
  165. {    gx_image_enum *penum;
  166.     const int width = pim->Width;
  167.     const int height = pim->Height;
  168.     const int bps = pim->BitsPerComponent;
  169.     bool masked = pim->ImageMask;
  170.     const float *decode = pim->Decode;
  171.     bool multi;
  172.     int index_bps;
  173.     const gs_color_space *pcs = pim->ColorSpace;
  174.     gs_logical_operation_t lop = pis->log_op;
  175.     int code;
  176.     gs_matrix mat;
  177.     int log2_xbytes = (bps <= 8 ? 0 : arch_log2_sizeof_frac);
  178.     int spp, nplanes, spread;
  179.     uint bsize;
  180.     byte *buffer;
  181.     fixed mtx, mty;
  182.     gs_fixed_point row_extent, col_extent, x_extent, y_extent;
  183.     bool device_color;
  184.     gs_fixed_rect obox, cbox;
  185.     fixed adjust;
  186.  
  187.     if ( width < 0 || height < 0 )
  188.       return_error(gs_error_rangecheck);
  189.     switch ( format )
  190.       { case gs_image_format_chunky: multi = false; break;
  191.         case gs_image_format_component_planar: multi = true; break;
  192.         default: return_error(gs_error_rangecheck);
  193.       }
  194.     switch ( bps )
  195.        {
  196.        case 1: index_bps = 0; break;
  197.        case 2: index_bps = 1; break;
  198.        case 4: index_bps = 2; break;
  199.        case 8: index_bps = 3; break;
  200.        case 12: index_bps = 4; break;
  201.        default: return_error(gs_error_rangecheck);
  202.        }
  203.     if ( prect )
  204.       { if ( prect->p.x < 0 || prect->p.y < 0 ||
  205.          prect->q.x < prect->p.x || prect->q.y < prect->p.y ||
  206.          prect->q.x > width || prect->q.y > height
  207.            )
  208.           return_error(gs_error_rangecheck);
  209.       }
  210.     if ( (code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
  211.          (code = gs_matrix_multiply(&mat, &ctm_only(pis), &mat)) < 0 ||
  212.          (code =
  213.           gs_distance_transform2fixed((const gs_matrix_fixed *)&mat,
  214.                       (floatp)width, (floatp)0,
  215.                       &row_extent)) < 0 ||
  216.          (code =
  217.           gs_distance_transform2fixed((const gs_matrix_fixed *)&mat,
  218.                       (floatp)0, (floatp)height,
  219.                       &col_extent)) < 0
  220.        )
  221.       return code;
  222.     penum = gs_alloc_struct(mem, gx_image_enum, &st_gx_image_enum,
  223.                 "gx_default_begin_image");
  224.     if ( penum == 0 )
  225.       return_error(gs_error_VMerror);
  226.     if ( prect )
  227.       { penum->rect.x = prect->p.x, penum->rect.y = prect->p.y;
  228.         penum->rect.w = prect->q.x - prect->p.x,
  229.           penum->rect.h = prect->q.y - prect->p.y;
  230.         if ( (code =
  231.           gs_distance_transform2fixed((const gs_matrix_fixed *)&mat,
  232.                           (floatp)penum->rect.w, (floatp)0,
  233.                           &x_extent)) < 0 ||
  234.          (code =
  235.           gs_distance_transform2fixed((const gs_matrix_fixed *)&mat,
  236.                           (floatp)0, (floatp)penum->rect.h,
  237.                           &y_extent)) < 0
  238.            )
  239.           { gs_free_object(mem, penum, "gx_default_begin_image");
  240.             return code;
  241.           }
  242.       }
  243.     else
  244.       { penum->rect.x = 0, penum->rect.y = 0;
  245.         penum->rect.w = width, penum->rect.h = height;
  246.         x_extent = row_extent;
  247.         y_extent = col_extent;
  248.       }
  249.     if ( (penum->masked = masked) )
  250.       {    /* This is imagemask. */
  251.         if ( bps != 1 || multi || pcs != NULL ||
  252. #ifdef DPNEXT
  253.              pim->HasAlpha ||
  254. #endif
  255.              !((decode[0] == 0.0 && decode[1] == 1.0) ||
  256.                (decode[0] == 1.0 && decode[1] == 0.0))
  257.            )
  258.           { gs_free_object(mem, penum, "gx_default_begin_image");
  259.             return_error(gs_error_rangecheck);
  260.           }
  261.         /* Initialize color entries 0 and 255. */
  262.         color_set_pure(&penum->icolor0, gx_no_color_index);
  263.         penum->icolor1 = *pdcolor;
  264.         memcpy(&penum->map[0].table.lookup4x1to32[0],
  265.                (decode[0] == 0 ? lookup4x1to32_inverted :
  266.             lookup4x1to32_identity),
  267.                16 * 4);
  268.         penum->map[0].decoding = sd_none;
  269.         spp = 1;
  270.         adjust = (pim->adjust ? float2fixed(0.25) : fixed_0);
  271.         lop = rop3_know_S_0(lop);
  272.       }
  273.     else
  274.       {    /* This is image, not imagemask. */
  275.         const gs_color_space_type _ds *pcst = pcs->type;
  276.         int b_w_color;
  277.  
  278.         spp = pcst->num_components;
  279.         if ( spp < 0 )        /* Pattern not allowed */
  280.           { gs_free_object(mem, penum, "gx_default_begin_image");
  281.             return_error(gs_error_rangecheck);
  282.           }
  283. #ifdef DPNEXT
  284.         if ( pim->HasAlpha )
  285.           ++spp;
  286. #endif
  287.         if ( spp == 1 )
  288.           multi = false;
  289.         device_color = (*pcst->concrete_space)(pcs, pis) == pcs;
  290.         image_init_colors(penum, bps, spp, multi, decode, pis, dev,
  291.                   pcs, &device_color);
  292.         adjust = fixed_0;
  293.         /* Try to transform non-default RasterOps to something */
  294.         /* that we implement less expensively. */
  295.         if ( !pim->CombineWithColor )
  296.           lop = rop3_know_T_0(lop);
  297.         else
  298.           { if ( rop3_uses_T(lop) )
  299.               switch ( color_draws_b_w(dev, pdcolor) )
  300.             {
  301.             case 0:
  302.               lop = rop3_know_T_0(lop); break;
  303.             case 1:
  304.               lop = rop3_know_T_1(lop); break;
  305.             default:
  306.               ;
  307.             }
  308.           }
  309.         if ( lop != rop3_S && /* if best case, no more work needed */
  310.              !rop3_uses_T(lop) && bps == 1 && spp == 1 &&
  311.              (b_w_color =
  312.               color_draws_b_w(dev, &penum->icolor0)) >= 0 &&
  313.              color_draws_b_w(dev, &penum->icolor1) == (b_w_color ^ 1)
  314.            )
  315.           { if ( b_w_color )
  316.               { /* Swap the colors and invert the RasterOp source. */
  317.             gx_device_color dcolor;
  318.             dcolor = penum->icolor0;
  319.             penum->icolor0 = penum->icolor1;
  320.             penum->icolor1 = dcolor;
  321.             lop = rop3_invert_S(lop);
  322.               }
  323.             /*
  324.              * At this point, we know that the source pixels
  325.              * correspond directly to the S input for the raster op,
  326.              * i.e., icolor0 is black and icolor1 is white.
  327.              */
  328.             switch ( lop )
  329.             {
  330.             case rop3_D & rop3_S:
  331.               /* Implement this as an inverted mask writing 0s. */
  332.               penum->icolor1 = penum->icolor0;
  333.               /* (falls through) */
  334.             case rop3_D | rop3_not(rop3_S):
  335.               /* Implement this as an inverted mask writing 1s. */
  336.               memcpy(&penum->map[0].table.lookup4x1to32[0],
  337.                  lookup4x1to32_inverted, 16 * 4);
  338. rmask:              /* Fill in the remaining parameters for a mask. */
  339.               penum->masked = masked = true;
  340.               color_set_pure(&penum->icolor0, gx_no_color_index);
  341.               penum->map[0].decoding = sd_none;
  342.               lop = rop3_T;
  343.               break;
  344.             case rop3_D & rop3_not(rop3_S):
  345.               /* Implement this as a mask writing 0s. */
  346.               penum->icolor1 = penum->icolor0;
  347.               /* (falls through) */
  348.             case rop3_D | rop3_S:
  349.               /* Implement this as a mask writing 1s. */
  350.               memcpy(&penum->map[0].table.lookup4x1to32[0],
  351.                  lookup4x1to32_identity, 16 * 4);
  352.               goto rmask;
  353.             default:
  354.               ;
  355.             }
  356.           }
  357.       }
  358.     penum->device_color = device_color;
  359.     /* Round up the width, +1 for an end-of-run byte. */
  360.     bsize = ((bps > 8 ? width * 2 : width) + 8) * spp;
  361.     buffer = gs_alloc_bytes(mem, bsize, "image buffer");
  362.     if ( buffer == 0 )
  363.       { gs_free_object(mem, penum, "gx_default_begin_image");
  364.         return_error(gs_error_VMerror);
  365.       }
  366.     penum->bps = bps;
  367.     penum->unpack_bps = bps;
  368.     penum->log2_xbytes = log2_xbytes;
  369.     penum->spp = spp;
  370. #ifdef DPNEXT
  371.     penum->has_alpha = pim->HasAlpha;
  372. #endif
  373.     nplanes = (multi ? spp : 1);
  374.     penum->num_planes = nplanes;
  375.     spread = nplanes << log2_xbytes;
  376.     penum->spread = spread;
  377.     penum->matrix = mat;
  378.     penum->x_extent = x_extent;
  379.     penum->y_extent = y_extent;
  380.     penum->posture =
  381.       ((x_extent.y | y_extent.x) == 0 ? image_portrait :
  382.        (x_extent.x | y_extent.y) == 0 ? image_landscape :
  383.        image_skewed);
  384.     mtx = float2fixed(mat.tx);
  385.     mty = float2fixed(mat.ty);
  386.     penum->pis = pis;
  387.     penum->pcs = pcs;
  388.     penum->memory = mem;
  389.     penum->dev = dev;
  390.     penum->buffer = buffer;
  391.     penum->buffer_size = bsize;
  392.     penum->line = 0;
  393.     penum->line_size = 0;
  394. #ifdef FUTURE
  395.     /*
  396.      * If we're asked to interpolate in a partial image, we have to
  397.      * assume that the client either really only is interested in
  398.      * the given sub-image, or else is constructing output out of
  399.      * overlapping pieces.
  400.      */
  401.     penum->interpolate = pim->Interpolate;
  402. #else
  403.     /* Interpolation in a partial image (probably) doesn't make sense. */
  404.     penum->interpolate =
  405.       pim->Interpolate &&
  406.       !(penum->rect.x | penum->rect.y |
  407.         (width - penum->rect.w) | (height - penum->rect.h));
  408. #endif
  409.     penum->use_rop = lop != (masked ? rop3_T : rop3_S);
  410. #ifdef DEBUG
  411.     if ( gs_debug_c('*') )
  412.       { if ( penum->use_rop )
  413.           dprintf1("[%03x]", lop);
  414.         dprintf5("%c%d%c%dx%d ",
  415.              (masked ? (color_is_pure(pdcolor) ? 'm' : 'h') : 'i'),
  416.              bps,
  417.              (penum->posture == image_portrait ? ' ' :
  418.               penum->posture == image_landscape ? 'L' : 'T'),
  419.              width, height);
  420.       }
  421. #endif
  422.     penum->slow_loop = 0;
  423.     if ( pcpath == 0 )
  424.       { (*dev_proc(dev, get_clipping_box))(dev, &obox);
  425.         cbox = obox;
  426.         penum->clip_image = 0;
  427.       }
  428.     else
  429.       penum->clip_image =
  430.         (gx_cpath_outer_box(pcpath, &obox) |    /* not || */
  431.          gx_cpath_inner_box(pcpath, &cbox) ?
  432.          0 : image_clip_region);
  433.     penum->clip_outer = obox;
  434.     penum->clip_inner = cbox;
  435.     penum->log_op = rop3_T;        /* rop device takes care of this */
  436.     penum->clip_dev = 0;        /* in case we bail out */
  437.     penum->rop_dev = 0;        /* ditto */
  438.     penum->scaler = 0;        /* ditto */
  439.     /*
  440.      * If all four extrema of the image fall within the clipping
  441.      * rectangle, clipping is never required.  When making this check,
  442.      * we must carefully take into account the fact that we only care
  443.      * about pixel centers.
  444.      */
  445.        {    fixed
  446.           epx = min(row_extent.x, 0) + min(col_extent.x, 0),
  447.           eqx = max(row_extent.x, 0) + max(col_extent.x, 0),
  448.           epy = min(row_extent.y, 0) + min(col_extent.y, 0),
  449.           eqy = max(row_extent.y, 0) + max(col_extent.y, 0);
  450.  
  451.         { int hwx, hwy;
  452.  
  453.           switch ( penum->posture )
  454.             {
  455.             case image_portrait:
  456.               hwx = width, hwy = height;
  457.               break;
  458.             case image_landscape:
  459.               hwx = height, hwy = width;
  460.               break;
  461.             default:
  462.               hwx = hwy = 0;
  463.             }
  464.           /*
  465.            * If the image is only 1 sample wide or high,
  466.            * and is less than 1 device pixel wide or high,
  467.            * move it slightly so that it covers pixel centers.
  468.            * This is a hack to work around a bug in some old
  469.            * versions of TeX/dvips, which use 1-bit-high images
  470.            * to draw horizontal and vertical lines without
  471.            * positioning them properly.
  472.            */
  473.           if ( hwx == 1 && eqx - epx < fixed_1 )
  474.             { fixed diff =
  475.             arith_rshift_1(row_extent.x + col_extent.x);
  476.               mtx = (((mtx + diff) | fixed_half) & -fixed_half) - diff;
  477.             }
  478.           if ( hwy == 1 && eqy - epy < fixed_1 )
  479.             { fixed diff =
  480.             arith_rshift_1(row_extent.y + col_extent.y);
  481.               mty = (((mty + diff) | fixed_half) & -fixed_half) - diff;
  482.             }
  483.         }
  484.         if_debug11('b',
  485.                "[b]Image: cbox=(%g,%g),(%g,%g), obox=(%g,%g),(%g,%g)\n    mt=(%g,%g) clip_image=0x%x\n",
  486.                fixed2float(cbox.p.x), fixed2float(cbox.p.y),
  487.                fixed2float(cbox.q.x), fixed2float(cbox.q.y),
  488.                fixed2float(obox.p.x), fixed2float(obox.p.y),
  489.                fixed2float(obox.q.x), fixed2float(obox.q.y),
  490.                fixed2float(mtx), fixed2float(mty),
  491.                penum->clip_image);
  492.         dda_init(penum->dda.row.x, mtx, col_extent.x, height);
  493.         dda_init(penum->dda.row.y, mty, col_extent.y, height);
  494.         if ( penum->rect.y )
  495.           { dda_advance(penum->dda.row.x, penum->rect.y);
  496.             dda_advance(penum->dda.row.y, penum->rect.y);
  497.           }
  498.         penum->cur.x = penum->prev.x = dda_current(penum->dda.row.x);
  499.         penum->cur.y = penum->prev.y = dda_current(penum->dda.row.y);
  500.         dda_init(penum->dda.pixel0.x, penum->cur.x, row_extent.x,
  501.              width);
  502.         dda_init(penum->dda.pixel0.y, penum->cur.y, row_extent.y,
  503.              width);
  504.         if ( penum->rect.x )
  505.           { dda_advance(penum->dda.pixel0.x, penum->rect.x);
  506.             dda_advance(penum->dda.pixel0.y, penum->rect.x);
  507.           }
  508.         { fixed ox = dda_current(penum->dda.pixel0.x);
  509.           fixed oy = dda_current(penum->dda.pixel0.y);
  510.           if ( !penum->clip_image )    /* i.e., not clip region */
  511.             penum->clip_image =
  512.               (fixed_pixround(ox + epx) < fixed_pixround(cbox.p.x) ?
  513.                image_clip_xmin : 0) +
  514.               (fixed_pixround(ox + eqx) >= fixed_pixround(cbox.q.x) ?
  515.                image_clip_xmax : 0) +
  516.               (fixed_pixround(oy + epy) < fixed_pixround(cbox.p.y) ?
  517.                image_clip_ymin : 0) +
  518.               (fixed_pixround(oy + eqy) >= fixed_pixround(cbox.q.y) ?
  519.                image_clip_ymax : 0);
  520.         }
  521.        }
  522.     penum->y = 0;
  523.     penum->adjust = adjust;
  524.        {    static sample_unpack_proc((*procs[4])) = {
  525.             sample_unpack_1, sample_unpack_2,
  526.             sample_unpack_4, sample_unpack_8
  527.            };
  528.         if ( index_bps == 4 )
  529.           { if ( (penum->unpack = sample_unpack_12_proc) == 0 )
  530.               { /* 12-bit samples are not supported. */
  531.             gx_default_end_image(dev, penum, false);
  532.             return_error(gs_error_rangecheck);
  533.               }
  534.           }
  535.         else
  536.           {    penum->unpack = procs[index_bps];
  537.             if_debug1('b', "[b]unpack=%d\n", bps);
  538.           }
  539. #define use_strategy(sp)\
  540.   (image_strategies.sp != 0 &&\
  541.    (penum->render = (*image_strategies.sp)(penum)) != 0)
  542.         if (
  543.                use_strategy(interpolate) ||
  544.                use_strategy(simple) ||
  545.                use_strategy(fracs) ||
  546.                use_strategy(mono) ||
  547.                use_strategy(color)
  548.              )
  549.           DO_NOTHING;
  550. #undef use_strategy
  551.         else
  552.           { /* No available strategy can handle this image. */
  553.             gx_default_end_image(dev, penum, false);
  554.             return_error(gs_error_rangecheck);
  555.           }
  556.        }
  557.     if ( penum->clip_image && pcpath )
  558.       {    /* Set up the clipping device. */
  559.         gx_device_clip *cdev =
  560.           gs_alloc_struct(mem, gx_device_clip,
  561.                   &st_device_clip, "image clipper");
  562.         if ( cdev == 0 )
  563.           {    gx_default_end_image(dev, penum, false);
  564.             return_error(gs_error_VMerror);
  565.           }
  566.         gx_make_clip_device(cdev, cdev, &pcpath->list);
  567.         cdev->target = dev;
  568.         (*dev_proc(cdev, open_device))((gx_device *)cdev);
  569.         penum->clip_dev = cdev;
  570.       }
  571.     if ( penum->use_rop )
  572.       {    /* Set up the RasterOp source device. */
  573.         gx_device_rop_texture *rtdev =
  574.           gs_alloc_struct(mem, gx_device_rop_texture,
  575.                   &st_device_rop_texture, "image RasterOp");
  576.         if ( rtdev == 0 )
  577.           {    gx_default_end_image(dev, penum, false);
  578.             return_error(gs_error_VMerror);
  579.           }
  580.         gx_make_rop_texture_device(rtdev,
  581.                       (penum->clip_dev != 0 ?
  582.                        (gx_device *)penum->clip_dev :
  583.                        dev), lop, pdcolor);
  584.         penum->rop_dev = rtdev;
  585.       }
  586.     if_debug8('b', "[b]Image: w=%d h=%d [%g %g %g %g %g %g]\n",
  587.          width, height,
  588.          mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
  589.     *pinfo = penum;
  590.     return 0;
  591. }
  592.  
  593. /* If a drawing color is black or white, return 0 or 1 respectively, */
  594. /* otherwise return -1. */
  595. private int
  596. color_draws_b_w(gx_device *dev, const gx_drawing_color *pdcolor)
  597. {    if ( color_is_pure(pdcolor) )
  598.       { gx_color_value rgb[3];
  599.         (*dev_proc(dev, map_color_rgb))(dev, gx_dc_pure_color(pdcolor),
  600.                         rgb);
  601.         if ( !(rgb[0] | rgb[1] | rgb[2]) )
  602.           return 0;
  603.         if ( (rgb[0] & rgb[1] & rgb[2]) == gx_max_color_value )
  604.           return 1;
  605.       }
  606.     return -1;
  607. }
  608.  
  609. /* Initialize the color mapping tables for a non-mask image. */
  610. private void
  611. image_init_colors(gx_image_enum *penum, int bps, int spp, bool multi,
  612.   const float *decode /*[spp*2]*/, const gs_imager_state *pis, gx_device *dev,
  613.   const gs_color_space *pcs, bool *pdcb)
  614. {    int ci;
  615.     static const float default_decode[] =
  616.       { 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
  617. #ifdef DPNEXT
  618.         , 0.0, 1.0
  619. #endif
  620.       };
  621.  
  622.     /* Initialize the color table */
  623.  
  624. #define ictype(i)\
  625.   penum->clues[i].dev_color.type
  626.     switch ( (spp == 1 ? bps : 8) )
  627.     {
  628.     case 8:            /* includes all color images */
  629.     {    register gx_image_clue *pcht = &penum->clues[0];
  630.         register int n = 64;
  631.         do
  632.         {    pcht[0].dev_color.type =
  633.               pcht[1].dev_color.type =
  634.               pcht[2].dev_color.type =
  635.               pcht[3].dev_color.type =
  636.                 gx_dc_type_none;
  637.             pcht[0].key = pcht[1].key =
  638.               pcht[2].key = pcht[3].key = 0;
  639.             pcht += 4;
  640.         }
  641.         while ( --n > 0 );
  642.         penum->clues[0].key = 1;    /* guarantee no hit */
  643.         break;
  644.     }
  645.     case 4:
  646.         ictype(17) = ictype(2*17) = ictype(3*17) =
  647.           ictype(4*17) = ictype(6*17) = ictype(7*17) =
  648.           ictype(8*17) = ictype(9*17) = ictype(11*17) =
  649.           ictype(12*17) = ictype(13*17) = ictype(14*17) =
  650.             gx_dc_type_none;
  651.         /* falls through */
  652.     case 2:
  653.         ictype(5*17) = ictype(10*17) = gx_dc_type_none;
  654. #undef ictype
  655.     }
  656.  
  657.     /* Initialize the maps from samples to intensities. */
  658.  
  659.     for ( ci = 0; ci < spp; ci++ )
  660.     {    sample_map *pmap = &penum->map[ci];
  661.  
  662.         /* If the decoding is [0 1] or [1 0], we can fold it */
  663.         /* into the expansion of the sample values; */
  664.         /* otherwise, we have to use the floating point method. */
  665.  
  666.         const float *this_decode = &decode[ci * 2];
  667.         const float *map_decode;    /* decoding used to */
  668.                 /* construct the expansion map */
  669.  
  670.         const float *real_decode;    /* decoding for */
  671.                 /* expanded samples */
  672.  
  673.         bool no_decode;
  674.  
  675.         map_decode = real_decode = this_decode;
  676.         if ( map_decode[0] == 0.0 && map_decode[1] == 1.0 )
  677.             no_decode = true;
  678.         else if ( map_decode[0] == 1.0 && map_decode[1] == 0.0 )
  679.             no_decode = true,
  680.             real_decode = default_decode;
  681.         else
  682.             no_decode = false,
  683.             *pdcb = false,
  684.             map_decode = default_decode;
  685.         if ( bps > 2 || multi )
  686.         {    if ( bps <= 8 )
  687.               image_init_map(&pmap->table.lookup8[0], 1 << bps,
  688.                      map_decode);
  689.         }
  690.         else
  691.         {    /* The map index encompasses more than one pixel. */
  692.             byte map[4];
  693.             register int i;
  694.             image_init_map(&map[0], 1 << bps, map_decode);
  695.             switch ( bps )
  696.             {
  697.             case 1:
  698.             {    register bits32 *p = &pmap->table.lookup4x1to32[0];
  699.                 if ( map[0] == 0 && map[1] == 0xff )
  700.                   memcpy((byte *)p, lookup4x1to32_identity, 16 * 4);
  701.                 else if ( map[0] == 0xff && map[1] == 0 )
  702.                   memcpy((byte *)p, lookup4x1to32_inverted, 16 * 4);
  703.                 else
  704.                   for ( i = 0; i < 16; i++, p++ )
  705.                     ((byte *)p)[0] = map[i >> 3],
  706.                     ((byte *)p)[1] = map[(i >> 2) & 1],
  707.                     ((byte *)p)[2] = map[(i >> 1) & 1],
  708.                     ((byte *)p)[3] = map[i & 1];
  709.             }    break;
  710.             case 2:
  711.             {    register bits16 *p = &pmap->table.lookup2x2to16[0];
  712.                 for ( i = 0; i < 16; i++, p++ )
  713.                     ((byte *)p)[0] = map[i >> 2],
  714.                     ((byte *)p)[1] = map[i & 3];
  715.             }    break;
  716.             }
  717.         }
  718.         pmap->decode_base /* = decode_lookup[0] */ = real_decode[0];
  719.         pmap->decode_factor =
  720.           (real_decode[1] - real_decode[0]) /
  721.             (bps <= 8 ? 255.0 : (float)frac_1);
  722.         pmap->decode_max /* = decode_lookup[15] */ = real_decode[1];
  723.         if ( no_decode )
  724.             pmap->decoding = sd_none;
  725.         else if ( bps <= 4 )
  726.         {    int step = 15 / ((1 << bps) - 1);
  727.             int i;
  728.  
  729.             pmap->decoding = sd_lookup;
  730.             for ( i = 15 - step; i > 0; i -= step )
  731.               pmap->decode_lookup[i] = pmap->decode_base +
  732.                 i * (255.0 / 15) * pmap->decode_factor;
  733.         }
  734.         else
  735.             pmap->decoding = sd_compute;
  736.         if ( spp == 1 )        /* and ci == 0 */
  737.         {    /* Pre-map entries 0 and 255. */
  738.             gs_client_color cc;
  739.             cc.paint.values[0] = real_decode[0];
  740.             (*pcs->type->remap_color)(&cc, pcs, &penum->icolor0,
  741.                     pis, dev, gs_color_select_source);
  742.             cc.paint.values[0] = real_decode[1];
  743.             (*pcs->type->remap_color)(&cc, pcs, &penum->icolor1,
  744.                     pis, dev, gs_color_select_source);
  745.         }
  746.     }
  747.  
  748. }
  749. /* Construct a mapping table for sample values. */
  750. /* map_size is 2, 4, 16, or 256.  Note that 255 % (map_size - 1) == 0, */
  751. /* so the division 0xffffL / (map_size - 1) is always exact. */
  752. private void
  753. image_init_map(byte *map, int map_size, const float *decode)
  754. {    float min_v = decode[0];
  755.     float diff_v = decode[1] - min_v;
  756.  
  757.     if ( diff_v == 1 || diff_v == -1 )
  758.       { /* We can do the stepping with integers, without overflow. */
  759.         byte *limit = map + map_size;
  760.         uint value = min_v * 0xffffL;
  761.         int diff = diff_v * (0xffffL / (map_size - 1));
  762.  
  763.         for ( ; map != limit; map++, value += diff )
  764.           *map = value >> 8;
  765.       }
  766.     else
  767.       { /* Step in floating point, with clamping. */
  768.         int i;
  769.         for ( i = 0; i < map_size; ++i )
  770.           { int value = (int)((min_v + diff_v * i / (map_size - 1)) * 255);
  771.             map[i] = (value < 0 ? 0 : value > 255 ? 255 : value);
  772.           }
  773.       }
  774. }
  775.